package com.py.credit.controller;

import com.alibaba.fastjson.JSONObject;
import com.py.credit.common.logs.ExceptionLogger;
import com.py.credit.common.rest.RestServiceResult;
import com.py.credit.entity.DissentProcess;
import com.py.credit.entity.SysUser;
import com.py.credit.entity.Table;
import com.py.credit.service.*;
import com.py.credit.utils.FileUtil;
import com.py.credit.utils.MapCache;
import com.py.credit.utils.UuidUtil;
import com.py.framework.core.annotation.IgnoreAuthority;
import com.py.framework.core.common.Page;
import com.py.framework.core.helper.HttpServletHelper;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 前台异议处理控制器
 *
 * @author : YaoS
 * @version : project2.6
 * @date : 2019-01-17 12:09
 */
@RestController
@RequestMapping(value = "/dissentProcess")
public class DissentProcessController {

    @Autowired
    private RemoteBaseService remoteBaseService;
    @Autowired
    private DissentProcessService dissentProcessService;
    @Autowired
    private DataLineageService dataLineageService;
    @Autowired
    private ColumnService columnService;
    @Autowired
    private TableService tableService;

    private static String UPDATE = "U";
    private static String DELETE = "D";

    @Value("${frontDissentProcess}")
    private String frontPath;

    /**
     * 功能描述: 查询需要异议处理的数据
     *
     * @param tableId 表id
     * @param tybm    企业统一编码
     * @param page    分页对象
     * @return RestServiceResult
     * @author YaoS
     * @date 19/1/22 9:37
     */
    @IgnoreAuthority
    @RequestMapping(value = "/selectTableList.json")
    public RestServiceResult selectTableList(
            @RequestParam(value = "tableId", defaultValue = "", required = true) Integer tableId,
            @RequestParam(value = "tybm", defaultValue = "", required = true) String tybm,
            @RequestParam(value = "bm", defaultValue = "", required = true) String bm,
            Page page, HttpServletResponse httpResponse) {
        RestServiceResult<List<Map<String, Object>>> result = new RestServiceResult<>();
        List<String> showColumns = columnService.getColumnENByTableId(tableId);
        String tableName = tableService.getTableById(tableId).getResourceId();
        List<Map<String, Object>> tableList = tableService.getRecordsForPage(
                tybm, bm, tableId + "", tableName, showColumns,
                new String[]{"record_id", "tybm"}, "", page);
        return new RestServiceResult<>(page.getTotalCount(), tableList);
    }

    /**
     * 功能描述:添加前台异议处理
     *
     * @param qymc     企业名称
     * @param tyshxydm 统一社会信用代码
     * @param fddbr    法定代表人
     * @param tableId  表id
     * @param recordId 数据资源id
     * @param yynr     异议内容
     * @param file     证据文件
     * @return RestServiceResult
     * @author YaoS
     * @date 19/1/17 14:12
     */
    @IgnoreAuthority
    @RequestMapping(value = "/add.json")
    public RestServiceResult add(
            @RequestParam(value = "qymc", defaultValue = "", required = true) String qymc,
            @RequestParam(value = "tyshxydm", defaultValue = "", required = true) String tyshxydm,
            @RequestParam(value = "fddbr", defaultValue = "", required = true) String fddbr,
            @RequestParam(value = "tableId", defaultValue = "", required = true) Integer tableId,
            @RequestParam(value = "recordId", defaultValue = "", required = true) String recordId,
            @RequestParam(value = "yynr", defaultValue = "", required = true) String yynr,
            @RequestParam(value = "file") CommonsMultipartFile file,
            HttpServletResponse httpResponse) {
        RestServiceResult<Map<String, Object>> result = new RestServiceResult<Map<String, Object>>();
        //生成工作流key，业务表也需保存
        String accessKey = UuidUtil.getInstance().getUUid();
        DissentProcess dissentProcess = new DissentProcess();
        dissentProcess.setQymc(qymc);
        dissentProcess.setTyshxydm(tyshxydm);
        dissentProcess.setFddbr(fddbr);
        dissentProcess.setTableId(tableId);
        dissentProcess.setRecordId(recordId);
        try {
			yynr=URLEncoder.encode(yynr, "utf-8");
		} catch (UnsupportedEncodingException e) {
            ExceptionLogger.error("URLEncoder#encode", "表请转String错误！");

		}
        dissentProcess.setYynr(yynr);
        dissentProcess.setAccessKey(accessKey);
        //保存表单
        dissentProcessService.add(dissentProcess);
        int id = dissentProcess.getId();
        //获取文件名，同时对文件名中含有"\\"的转义去除
        String fileName = file.getOriginalFilename();
        if (fileName.contains("\\")) {
            fileName = StringUtils.substringAfterLast(fileName, "\\");
        }
        //文件类型校验
        String[] strings = new String[]{"zip", "7z", "rar"};
        String check = FileUtil.fileCheck(fileName, strings);
        if (!StringUtils.isEmpty(check)) {
            result.setCode(RestServiceResult.CODE_UNKNOW);
            result.setMsg(check);
            return result;
        }
        String resourceId = tableService.getTableById(dissentProcess.getTableId()).getResourceId();
        //查询数据拥有者id
        String dataOwner = dissentProcessService.selectDataOwner(resourceId, recordId);
        if (StringUtils.isEmpty(dataOwner)) {
            result.setCode(RestServiceResult.CODE_UNKNOW);
            result.setMsg("该条数据未查出数据拥有者，请与管理员联系！");
            return result;
        }
        //生成文件路径并保存文件
        String fileUrl = frontPath + File.separator + dissentProcess.getQymc() + File.separator + id + File.separator + fileName;
        byte[] fileBytes = file.getBytes();
        saveFile(fileBytes, fileUrl);
        dissentProcessService.saveFile(id, fileUrl);

        remoteBaseService.addWorkFlow("resourceYycl", accessKey, dataOwner, null, id + "", "“" + dissentProcess.getQymc() + "”前台异议处理", "",
                "5", "");
        return result;
    }

    /**
     * 保存文件到本地磁盘
     *
     * @param file
     * @param dest
     */
    private void saveFile(byte[] file, String dest) {
        try {
            FileUtils.writeByteArrayToFile(new File(dest), file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 功能描述: 查询异议申请数据
     *
     * @param id 业务数据id
     * @return RestServiceResult 申请处理的异议数据
     * @author YaoS
     * @date 19/1/21 17:38
     */
    @IgnoreAuthority
    @RequestMapping(value = "/getFrontDissentProcess.json")
    public RestServiceResult<Map> getFrontDissentProcess(
            @RequestParam(value = "id", defaultValue = "", required = true) String id,
            HttpServletRequest request) {
        RestServiceResult<Map> result = new RestServiceResult<>();
        // 获取当前用户信息
        RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
        SysUser userInfo = null;
        String[] configColumns = null;
        DissentProcess entity = dissentProcessService.getFrontDissentProcess(id);
        String tableName = tableService.getTableById(entity.getTableId()).getResourceId();
        HashMap<String, Object> map = new HashMap<>(3);
        if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
            userInfo = user.getData();
            if (null == userInfo || userInfo.getId() <= 0) {
                result.setCode(RestServiceResult.CODE_UNKNOW);
                result.setMsg("系统异常，请稍后再试！");
                ExceptionLogger.error("FrontDissentProcessController#getFrontDissentProcess", "未获取到当前用户信息！");
                return result;
            } else {
                configColumns = (String[]) MapCache.get(userInfo.getId() + "_" + tableName);
            }
        } else {
            result.setCode(user.getCode());
            result.setMsg(user.getMsg());
            return result;
        }
        List<String> showColumns = null;
        if (configColumns == null || configColumns.length == 0) {
            showColumns = columnService.getColumnENByTableId(entity.getTableId());
        } else {
            showColumns = Arrays.asList(configColumns);
        }
        try {
            Map<String, Object> tableMap = dissentProcessService.selectRecordsById(tableName, Integer.parseInt(entity.getRecordId()), showColumns);
            map.put("entity", entity);
            map.put("column", columnService.getColumn(entity.getTableId()));
            map.put("data", tableMap);
            result.setData(map);
            return result;
        } catch (Exception e) {
            ExceptionLogger.error("FrontDissentProcessController#getFrontDissentProcess", "查询异议处理详情异常！ERROR：" + e.getMessage(),
                    e);
            result.setCode(RestServiceResult.CODE_UNKNOW);
            result.setMsg("查询异议处理详情异常！" + e.getMessage());
            return result;
        }
    }

    /**
     * 功能描述: 前台回调查询数据拥有者id
     *
     * @param tableId  表id
     * @param recordId 数据id
     * @return
     * @author YaoS
     * @date 19/1/21 20:27
     */
    @RequestMapping(value = "/getDataOwner.json")
    public RestServiceResult<String> getDataOwner(
            @RequestParam(value = "tableId", defaultValue = "", required = true) Integer tableId,
            @RequestParam(value = "recordId", defaultValue = "", required = true) String recordId,
            HttpServletRequest request) {
        RestServiceResult<String> result = new RestServiceResult<>();
        String resourceId = tableService.getTableById(tableId).getResourceId();
        String dataOwner = dissentProcessService.selectDataOwner(resourceId, recordId);
        result.setData(dataOwner);
        return result;

    }

    /**
     * 功能描述: 查询展示数据字段名
     *
     * @param tableId 表id
     * @return RestServiceResult 查询展示的表字段
     * @author YaoS
     * @date 19/1/21 18:11
     */
    @IgnoreAuthority
    @RequestMapping(value = "/getColumns.json")
    public RestServiceResult<List<HashMap<String, String>>> getColumns(
            @RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
            HttpServletRequest request) {
        return new RestServiceResult<>(columnService.getColumn(tableId));
    }

    /**
     * 功能描述: 查询展示数据字段值
     *
     * @param tableId  表资源id
     * @param recordId 数据id
     * @return RestServiceResult 表具体值
     * @author YaoS
     * @date 19/1/21 18:11
     */
    @RequestMapping(value = "/getData.json")
    public RestServiceResult<Map<String, Object>> getData(
            @RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
            @RequestParam(value = "recordId", defaultValue = "", required = true) int recordId,
            HttpServletRequest request) {
        RestServiceResult<Map<String, Object>> result = new RestServiceResult();
        RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
        String tableName = tableService.getTableById(tableId).getResourceId();
        String[] configColumns = null;
        if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
            SysUser userInfo = user.getData();
            if (null != userInfo) {
                configColumns = (String[]) MapCache.get(userInfo.getId() + "_" + tableName);
            } else {
                ExceptionLogger.error("FrontDissentProcessController#getData", "未获取到当前用户信息！");
            }
        } else {
            ExceptionLogger.error("FrontDissentProcessController#getData", "未获取到当前用户信息！");
        }

        List<String> showColumns = null;
        if (configColumns == null || configColumns.length == 0) {
            showColumns = columnService.getColumnENByTableId(tableId);
        } else {
            showColumns = Arrays.asList(configColumns);
        }
        Map<String, Object> tableMap = dissentProcessService.selectRecordsById(tableName, recordId, showColumns);
        result.setData(tableMap);
        return result;
    }

    /**
     * 功能描述: 删除异议数据
     *
     * @param tableId  表资源id
     * @param recordId 数据id
     * @return
     * @author YaoS
     * @date 19/1/21 20:32
     */
    @RequestMapping(value = "/deleteData.json")
    public void deleteData(
            @RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
            @RequestParam(value = "recordId", defaultValue = "", required = true) int recordId,
            HttpServletRequest request) {
        dissentProcessService.deleteData(tableId, recordId);
    }


    /**
     * 功能描述: 查询当前用户异议数据记录列表
     *
     * @param bm        当前用户统一社会信用代码
     * @param startTime 申请时间
     * @return
     * @author YaoS
     * @date 19/1/22 17:30
     */
    @IgnoreAuthority
    @RequestMapping(value = "/selectHistoryList.json")
    public RestServiceResult selectHistoryListForPage(
            @RequestParam(value = "bm", defaultValue = "", required = true) String bm,
            @RequestParam(value = "type", defaultValue = "", required = true) String type,
            @RequestParam(value = "startTime", defaultValue = "", required = true) String startTime,
            @RequestParam(value = "endTime", defaultValue = "", required = true) String endTime,
            Page page, HttpServletRequest request) {
        RestServiceResult<List<Map<String, Object>>> result = new RestServiceResult<>();
        List<Map<String, Object>> tableList = dissentProcessService.selectHistoryListForPage(bm, type, startTime, endTime, page);
        return new RestServiceResult<>(page.getTotalCount(), tableList);
    }

    /**
     * 功能描述: 查询当前用户异议数据记录详情
     *
     * @param key 工作流key
     * @param id  申请时间
     * @return
     * @author YaoS
     * @date 19/1/22 17:30
     */
    @IgnoreAuthority
    @RequestMapping(value = "/selectHistoryDetail.json")
    public RestServiceResult selectHistoryDetail(
            @RequestParam(value = "key", defaultValue = "", required = true) String key,
            @RequestParam(value = "id", defaultValue = "", required = true) String id,
            HttpServletRequest request) {
        RestServiceResult<Map> result = new RestServiceResult<>();
        LinkedHashMap head = remoteBaseService.getDissentProcessHistory(key, id);
        DissentProcess body = dissentProcessService.getFrontDissentProcess(id);
        Table table = tableService.getTableById(body.getTableId());
        HashMap<String,Object> data= dissentProcessService.selectReviewData("t_"+table.getResourceId(),body.getRecordId());
        HashMap<String, Object> map = new HashMap<>(2);
        map.put("head", head);
        map.put("body", body);
        map.put("columns", columnService.getColumn(body.getTableId()));
        map.put("data", data);
        result.setData(map);
        return result;
    }

    /**
     * 功能描述:下载异议证据文件
     *
     * @param id 异议数据id
     * @return
     * @author YaoS
     * @date 19/1/23 9:28
     */
    @IgnoreAuthority
    @RequestMapping(value = "/downFile.json")
    public void downFile(
            @RequestParam(value = "id", defaultValue = "", required = true) String id,
            HttpServletResponse response, HttpServletRequest request) {
        DissentProcess entity = dissentProcessService.getFrontDissentProcess(id);
        FileUtil.downloadFile(entity.getFileUrl(), response);
    }

    /**
     * 功能描述: 异议处理重写定时任务
     *
     * @param type     删除D，修改U，无操作
     * @param tableId  表ID
     * @param recordId 数据ID
     * @param params   修改表的参数
     * @return
     * @author YaoS
     * @date 19/1/23 16:44
     */
    @IgnoreAuthority
    @RequestMapping(value = "/examineTask.json")
    public RestServiceResult examineTask(
            @RequestParam(value = "taskId", required = true) String taskId,
            @RequestParam(value = "procId", required = true) String procId,
            @RequestParam(value = "userId", required = false, defaultValue = "0") long userId,
            @RequestParam(value = "paramName", required = false) String paramName,
            @RequestParam(value = "paramValue", required = false) String paramValue,
            @RequestParam(value = "comment", required = false) String comment,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
            @RequestParam(value = "recordId", defaultValue = "", required = true) int recordId,
            @RequestParam(value = "params", defaultValue = "", required = true) String params,
            HttpServletResponse response, HttpServletRequest request) {
        RestServiceResult<Object> result = new RestServiceResult<>();
        RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
        SysUser userInfo = user.getData();
        //进行对应的业务处理
        if (UPDATE.equals(type)) {
            Map map = JSONObject.parseObject(params);
            boolean b = dataLineageService.updateData(tableId, recordId + "", map);
            if (!b) {
                result.setCode(RestServiceResult.CODE_UNKNOW);
                result.setMsg("该数据重复");
                return result;
            }
        } else if (DELETE.equals(type)) {
            dissentProcessService.deleteData(tableId, recordId);
        }
        try {
            //发送远程请求调用工作流
            remoteBaseService.examineTask(taskId, procId, userId + "", paramName,
                    paramValue, comment, userInfo, HttpServletHelper.getUserToken(request));
        } catch (Exception e) {
            result.setCode(RestServiceResult.CODE_UNKNOW);
            result.setMsg("调用远程进行工作流操作处理异常");
            return result;
        }
        return result;
    }

}
